Bamboo HR Adapter Authentication
Bamboo HR adapter supports two authentication/authorization mechanisms.
Basic Authorization with the static API Key (issued by the Bamboo HR organization admin user),
and their own flavour of the OpenID Connect.
Basic Authorization
To establish the Basic Authorization, an actor must create an API Key in their Bamboo HR organization, and then use it to authenticate the EasyBREAD client.
One API Key gives access to one Bamboo HR organization.
import { BreadOperationName } from '@easybread/operations';
// apiKey is issued by the Bamboo HR organization admin user.
export async function adapterBaomooHrAuthenticate(
breadId: string,
apiKey: string,
companyName: string
) {
const results = await client.invoke(BreadOperationName.SETUP_BASIC_AUTH, {
breadId,
payload: { apiKey, companyName }
});
if (results.rawPayload.success === false) {
throw new Error('Bamboo HR Setup Basic Auth Failed', {
cause: results.rawPayload
});
}
}
OpenID Connect Authentication
This option allows your application to authenticate users in their Bamboo HR organizations by using their Bamboo HR login and password.
Establishing the OpenID Connect authentication requires the following steps:
- Generate the OIDC authentication URL and redirect a user to it
- Receive the OIDC code from the callback URL and use it to get the authorization credentials and store them
OIDC Prerequisites
Login into BambooHR developer portal, and go to your Application (create one if you don't have it yet). It must look similar to this:

Register your redirect URI (you can register multiple).
Then, grab "Client ID", "Client Secret", and "API Key".
Store them in a secure place.
Note, never commit or share these values. They have to be kept secret.
OIDC Configuration
Configure the OIDC options in BambooHrAuthStrategy
import { load } from 'ts-dotenv';
// Read the OIDC configuration from the environment or the secret manager
const {
BAMBOO_HR_OID_CLIENT_ID,
BAMBOO_HR_OID_CLIENT_SECRET,
BAMBOO_HR_OID_REDIRECT_URI,
BAMBOO_HR_OID_APPLICATION_API_KEY,
} = load({
BAMBOO_HR_OID_CLIENT_ID: String,
BAMBOO_HR_OID_CLIENT_SECRET: String,
BAMBOO_HR_OID_REDIRECT_URI: String,
// application key is the API Key for your application in BambooHR developer portal
// (https://developers.bamboohr.com)
// Don't confuse it the with the API Key for your organization in BambooHR main app
// (https://{company-name}.bamboohr.com)
BAMBOO_HR_OID_APPLICATION_API_KEY: String,
});
// Option 1: Setup in constructor when creatinn an instance
const authStrategy = new BambooHrAuthStrategy(stateAdapter, {
oidcOptions: {
clientId: BAMBOO_HR_OID_CLIENT_ID,
clientSecret: BAMBOO_HR_OID_CLIENT_SECRET,
redirectUri: BAMBOO_HR_OID_REDIRECT_URI,
applicationKey: BAMBOO_HR_OID_APPLICATION_API_KEY,
},
});
// Option 2: using configureOidc() method on an existing instance
authStrategy.configureOidc({
clientId: BAMBOO_HR_OID_CLIENT_ID,
clientSecret: BAMBOO_HR_OID_CLIENT_SECRET,
redirectUri: BAMBOO_HR_OID_REDIRECT_URI,
applicationKey: BAMBOO_HR_OID_APPLICATION_API_KEY,
});
OIDC Step 1: Generate the OIDC authentication URL
Use the BambooHrOperationName.OIDC_AUTH_START operation to generate the OIDC authentication URL.
Then redirect the user there.
export async function bambooHrOidcAuthStart(breadId: string, companyName: string) {
// generate the OIDC authentication URL
const output = await clientBambooHr.invoke(
BambooHrOperationName.OIDC_AUTH_START,
{
breadId,
payload: { companyName },
}
);
// check if the operation was successful
if (!output.rawPayload.success) {
throw new Error('Bamboo HR Setup Basic Auth Failed', {
cause: output.rawPayload.error,
});
}
// the URL to redirect the user to
return output.rawPayload.data.authUri;
}
OIDC Step 2: Exchange the OIDC code for the authorization credentials
After the user logs in, you will receive the OIDC code and state query parameters in the callback URL.
Read them and use to call the BambooHrOperationName.OIDC_AUTH_COMPLETE operation.
export async function bambooHrOidcAuthComplete(breadId: string, code: string, state: string) {
const results = await clientBambooHr.invoke(
BambooHrOperationName.OIDC_AUTH_COMPLETE,
{
breadId,
payload: { code, state },
}
);
if (results.rawPayload.success === false) {
throw new Error('Bamboo HR OIDC Auth Complete Failed', {
cause: results.rawPayload.error
});
}
// companyName is the company name that was used to generate the OIDC URL
// you can use it in your app if needed.
const { companyName } = results.rawPayload.data;
return { companyName };
}
OIDC under the hood
Under the hood the process is a bit more complex.
- EasyBREAD generates the
stateparameter and store in the state alongside the given company name. The state key is derived form thebreadId. We call this theConnection Attemptstate. - The OIDC authentication URL is generated with the
stateparameter. - The user logs in and BambooHR redirects the user back to the EasyBREAD callback URL with the OIDC authentication
codeandstatequery parameters. - EasyBREAD retrieves the
Connection Attemptstate bybreadIdand verifies the authenticity of thestateparameter. - EasyBREAD then uses the company name from the
Connection Attempt, and OIDC authcodeto create anAccess Token. - EasyBREAD uses the access token to retrieve the
API Keyfrom BambooHR on behalf of the user (BambooHR will create one, if it doesn't exist yet) and stores it in the state.
The end result is the same as with the Basic Authorization method with the static API Key, but this time,
the API Key is created and retrieved dynamically on behalf of the user using the OIDC auth credentials.
EasyBREAD stores the API Key, not the Access Token.